home *** CD-ROM | disk | FTP | other *** search
- /*
- File: USB_ClassDriverAccess.c
-
- Contains: All routines that directly access the USB Class Driver.
-
- Version: 1.0
-
- Copyright: © 1999-2000 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include "USB_ClassDriverAccess.h"
- #include "USB_ManualEjectSupport.h"
- #include "USB_StdCommands.h"
-
- static StorageClassDispatchTablePtr gItsTheDispatchTable = nil; // The class's dispatch table
-
- // This parameter block is used by the insternal state machines
- // to allow them to perform device requests which are transparent outside this module
- static IntDriveRequestPB gInternalRequestPB[2];
-
- // Purposes for the Internal PBs
- enum
- {
- kGeneralUsagePB = 0,
- kManualEjectPB = 1
- };
-
- static Boolean ManualEjectInProgess = false;
- static Boolean GeneralIORequestWaiting = false;
-
- #pragma mark --
- Boolean IsClassDispatchTableValid( void )
- {
- if ( gItsTheDispatchTable != nil )
- {
- return true;
- }
-
- return false;
- }
-
- void SetClassDispatchTable( StorageClassDispatchTablePtr newValue )
- {
- if ( newValue != nil )
- {
- if ( newValue->dispatchTableVersion == kDispatchTableVersion )
- {
- gItsTheDispatchTable = newValue;
- }
- else
- {
- gItsTheDispatchTable = nil;
- }
- }
- else
- {
- gItsTheDispatchTable = nil;
- }
- }
-
- OSStatus InitializeClassAccess( void )
- {
- OSStatus status;
-
- status = ((gItsTheDispatchTable)->pStorageInitialize)();
- return status;
- }
-
- OSStatus TerminateClassAccess( void )
- {
- OSStatus status = noErr;
-
- if(gItsTheDispatchTable != nil)
- {
- status = ((gItsTheDispatchTable)->pStorageTerminate)();
- }
-
- gItsTheDispatchTable = nil;
- return status;
- }
-
- OSStatus SendClassStatusCall( UInt32 selectorCode, void *dataBuffer )
- {
- OSStatus status;
-
- status = ((gItsTheDispatchTable)->pStorageStatus)(selectorCode, dataBuffer);
- return status;
- }
-
- OSStatus SendClassControlCall( UInt32 selectorCode, void *dataBuffer )
- {
- OSStatus status;
-
- status = ((gItsTheDispatchTable)->pStorageControl)(selectorCode, dataBuffer);
- return status;
- }
-
- #pragma mark --
-
- // Functions for handling allocation of Parameter Blocks for requests
- IntDriveRequestPBPtr GetDriveInternalPB( void )
- {
- if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
- {
- // The PB is in use, return nil
- return nil;
- }
-
- CancelManualEjectInterrupt();
- BlockZero( &gInternalRequestPB[kGeneralUsagePB], sizeof (IntDriveRequestPB));
- gInternalRequestPB[kGeneralUsagePB].inUse = true;
- return &gInternalRequestPB[kGeneralUsagePB];
- }
-
- void FreeInternalPB( IntDriveRequestPBPtr intDrivePB )
- {
- intDrivePB->inUse = false;
- ResetManualEjectInterrupt();
- }
-
- Boolean IsCommandPending( void )
- {
- return ( gInternalRequestPB[kGeneralUsagePB].inUse || gInternalRequestPB[kManualEjectPB].inUse);
- }
-
- // Functions for handling allocation of Parameter Blocks for requests
- IntDriveRequestPBPtr GetManualEjectPB( void )
- {
- if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
- {
- // The PB is in use, return nil
- return nil;
- }
-
- BlockZero( &gInternalRequestPB[kManualEjectPB], sizeof (IntDriveRequestPB));
- gInternalRequestPB[kManualEjectPB].inUse = true;
- return &gInternalRequestPB[kManualEjectPB];
- }
-
- void FreeManualEjectPB( IntDriveRequestPBPtr intDrivePB )
- {
- intDrivePB->inUse = false;
- }
-
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Prevent and Allow Removal
- // All functions and variables needed to handle setting the
- // ability to eject the media in the attached device.
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Send Command to device
- OSStatus SendDeviceRequest( StorageExecuteCommandPB *commandPB )
- {
- OSStatus status = offLinErr;
-
- if (gItsTheDispatchTable)
- {
- if ( commandPB == &gInternalRequestPB[kGeneralUsagePB].executePB )
- {
- // This is the general use PB, check if there is a manual
- // eject request already in progress.
- if ( ManualEjectInProgess == true )
- {
- GeneralIORequestWaiting = true;
- return kRequestPending;
- }
- }
- else
- {
- if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
- {
- // There is IO going on, return an error and do not try
- // to send the Manual Eject PB.
- return ioErr;
- }
- else
- {
- ManualEjectInProgess = true;
- }
- }
-
-
- status = (gItsTheDispatchTable->pStorageExecuteCmd)(commandPB);
- }
-
- return status;
- }
-
- // Completion routine for these commands
- void DeviceRequestCompletion(void *thePB)
- {
- IntDriveRequestPBPtr requestPB;
- Boolean isManEject = false;
-
- requestPB = (IntDriveRequestPBPtr) thePB;
- if ( requestPB == &gInternalRequestPB[kManualEjectPB])
- {
- isManEject = true;
- ManualEjectInProgess = false;
- }
- else
- {
- isManEject = false;
- }
-
- requestPB->status = requestPB->executePB.status;
-
- if ( requestPB->executePB.autoStatusIsValid == true )
- {
- requestPB->autoStatusIsValid = false;
- //requestPB->autoStatusIsValid = theDrivePB->executePB.autoStatusIsValid;
- requestPB->autoStatus[0] = requestPB->executePB.autoStatus[0];
- requestPB->autoStatus[1] = requestPB->executePB.autoStatus[1];
- }
-
- if ( (isManEject == true) && ( GeneralIORequestWaiting == true ))
- {
- OSStatus theStatus = noErr;
-
- GeneralIORequestWaiting = false;
- FreeManualEjectPB( &gInternalRequestPB[kManualEjectPB] );
- theStatus = SendDeviceRequest( &gInternalRequestPB[kGeneralUsagePB].executePB );
- if ( theStatus != kRequestPending )
- {
- gInternalRequestPB[kGeneralUsagePB].executePB.status = gInternalRequestPB[kGeneralUsagePB].status = theStatus;
- (*((InternalCompletionProcPtr) gInternalRequestPB[kGeneralUsagePB].completionProc)) ( &gInternalRequestPB[kGeneralUsagePB] );
- }
- }
- else
- {
- (*((InternalCompletionProcPtr) requestPB->completionProc)) ( requestPB );
- }
- }
-
- OSStatus AbortPendingCommand( void )
- {
- OSStatus status = noErr;
-
- if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
- {
- // We have a pending command, Go ahead and Abort it
- //SysDebugStr("\pWatchDog timer went off");
-
- status = ((gItsTheDispatchTable)->pStorageControl)(kUSBStorageControlAbortCommand, &gInternalRequestPB[kGeneralUsagePB].executePB);
- }
-
- return status;
- }
-
-